/**
 * desc: 第三方与 UDC 标准页面通信的 SDK
 * author: zhongpz@seeyon.com
 */
import UdcComponent from "./UdcComponent";
import { currentSDK } from '../../index';
;
/** 消息身份标识，消息一级认证标识 */
const _identifying = "__SEEYON_UDC__";
/** SDK支持的消息类型枚举  */
export var MessageTypeEnum;
(function (MessageTypeEnum) {
    MessageTypeEnum["callMethod"] = "callMethod";
    MessageTypeEnum["message"] = "message";
    MessageTypeEnum["callEvent"] = "callEvent";
})(MessageTypeEnum || (MessageTypeEnum = {}));
;
/** UDC SDK支持的方法名枚举，在UDC平台需要有对应的方法支持  */
export var MethodNameEnum;
(function (MethodNameEnum) {
    MethodNameEnum["ready"] = "ready";
    MethodNameEnum["insertComponent"] = "insertComponent";
})(MethodNameEnum || (MethodNameEnum = {}));
;
;
;
;
;
;
;
;
export default class UdcSdkForIfame {
    constructor() {
        this._nameSpaceId = this._uuid();
    }
    /** 消息一级标识  */
    _identifying = _identifying;
    /** 当前页面唯一标识  */
    _nameSpaceId;
    /** SDK准备完成标识  */
    _is_ready = false;
    /** 自定义事件池  */
    _customEvents = {};
    /** UUID生成函数  */
    _uuid() {
        const uuid = "xxx_xxxx_xxxx_yxxx_xxxx".replace(/[xy]/g, (c) => {
            const r = (Math.random() * 16) | 0;
            const v = c === "x" ? r : (r & 0x3) | 0x8;
            return `${v.toString(16)}`;
        });
        return `x${uuid}`;
    }
    /** 接收消息合法性校验  */
    _msgValidator(message) {
        if (Object.prototype.toString.call(message) === "[object Object]" && //  判断数据格式是否正确
            message._identifying === _identifying && // 判断身份标识是否正确
            MessageTypeEnum[message.type] && // 判断消息类型是否合规
            message._nameSpaceId === this._nameSpaceId // 命名空间是否匹配
        ) {
            return true;
        }
        return false;
    }
    /** 事件监听函数  */
    _eventListener = (e, callBack) => {
        try {
            const message = e.data;
            if (!this._msgValidator(message)) {
                return;
            }
            //  ready 回调
            this._readyCallBack(message, callBack);
            //  事件调用
            this._callEvent(message);
        }
        catch (e) {
            console.error(e);
        }
    };
    /** SDK Ready Callback  */
    _readyCallBack(message, callBack) {
        const signatureMethods = message.data?.signatureMethods;
        const version = message.data?.version;
        if (message.type === MessageTypeEnum.message &&
            message.data?.status === "ready" &&
            !this._is_ready) {
            this._is_ready = true;
            callBack && callBack(this, {
                parentRuntimeContext: null,
                runtimeContext: null
            });
        }
    }
    /** 事件监听句柄函数  */
    _eventListenerHandler = () => void (0);
    /** 注册事件监听  */
    _registerEventListener(callBack) {
        this._eventListenerHandler = (e) => {
            this._eventListener(e, callBack);
        };
        window.addEventListener("message", this._eventListenerHandler);
    }
    /** 事件调用For _customEvents  */
    _callEvent(message) {
        if (message.type !== MessageTypeEnum.callEvent) {
            return;
        }
        const { callEvents } = message;
        callEvents?.forEach((event) => {
            const { id, type } = event;
            this._customEvents[id]?.[type]?.();
        });
    }
    /** 销毁实例 */
    destory() {
        window.removeEventListener("message", this._eventListenerHandler);
    }
    /** SDK内部消息发送函数  */
    postMessage(message) {
        if ((message.type === MessageTypeEnum.callMethod &&
            message.methodName === MethodNameEnum.ready) || // 初始化消息
            this._is_ready // SDK准备好
        ) {
            window.parent.postMessage({
                ...message,
                _identifying: this._identifying,
                _nameSpaceId: this._nameSpaceId,
            }, "*");
        }
    }
    /**
     * 契约组件: 在第三方页面声明的组件，在UDC一定存在相同组件。
     * 这类组件用于不需要获取UDC组件信息的场景，减少查询组件开销。
     * */
    contractComponent = (UdcComponentType, config) => {
        return new UdcComponent(this, {
            type: UdcComponentType,
            id: config?.id,
            isContract: true
        });
    };
    /** 创建组件 */
    createComponent = (componentContext) => {
        return new UdcComponent(this).createComponent(componentContext);
    };
    /** SDK 初始化成功后，通过callback函数可以安全的调用SDK */
    ready(callBack) {
        this.postMessage({
            type: MessageTypeEnum.callMethod,
            methodName: MethodNameEnum.ready,
        });
        this._registerEventListener(callBack);
    }
    /** 注册组件自定义事件 */
    registerComponentCustomEvents = ({ id, type, func }) => {
        if (!this._customEvents[id]) {
            this._customEvents[id] = {};
        }
        this._customEvents[id][type] = func;
    };
    /** 客制化服务 */
    _customization = {
        CMI: {
            /** 为SDK实例提供：插入按钮到工具栏指定索引位置的能力 */
            insertBtnForToolbar: (message) => {
                const { position, btns, id } = message;
                const $udcToolbar = this.contractComponent('UdcToolBar', { id });
                const $btns = [];
                btns?.forEach((btn) => {
                    $btns.push(this.createComponent({
                        type: 'UdcButton',
                        props: btn
                    }));
                });
                $udcToolbar.insertComponent($btns, {
                    position
                });
            }
        }
    };
    /** 获取客户定制API */
    getCustomApi = () => {
        const _tenant = currentSDK.baseInfo.tenant;
        const _tenantApi = this._customization[_tenant];
        if (!_tenantApi) {
            console.error(!_tenant ? '缺少tenant信息' : '该tenant未定制过API');
            return;
        }
        return _tenantApi;
    };
}
